package com.hjzd.ai.smartpractice.websocket;

import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.OutputFormatEnum;
import com.alibaba.nls.client.protocol.SampleRateEnum;
import com.alibaba.nls.client.protocol.tts.FlowingSpeechSynthesizer;
import com.alibaba.nls.client.protocol.tts.FlowingSpeechSynthesizerListener;
import com.alibaba.nls.client.protocol.tts.FlowingSpeechSynthesizerResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;

import static com.hjzd.ai.smartpractice.constant.ServiceConstant.TTS_PREFIX;

public class AliTtsClient {
    private static final Logger logger = LoggerFactory.getLogger(AliTtsClient.class);
    private final WebSocketSession session;
    private String appKey; // API Key
    private String token; // API Token
    private NlsClient client; // NlsClient 实例
    private FlowingSpeechSynthesizer synthesizer; // 语音合成器
    private final AtomicBoolean isPlaying = new AtomicBoolean(false); // 标记 TTS 是否正在播放
    private final AtomicBoolean isInterrupted = new AtomicBoolean(false); // 标记是否被打断

    public AliTtsClient(String appKey, String token, WebSocketSession session) {
        this.appKey = appKey;
        this.token = token;
        this.session = session;
        String url = "wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1";
        this.client = new NlsClient(url, token);
    }

    // 打断 TTS 播放
    public void interrupt() {
        isInterrupted.set(true);
    }

    // 创建语音合成器并设置监听器
    private FlowingSpeechSynthesizerListener createSynthesizerListener() {
        return new FlowingSpeechSynthesizerListener() {
            private FileOutputStream fout;

            // 流式文本语音合成开始
            public void onSynthesisStart(FlowingSpeechSynthesizerResponse response) {
                logger.info("合成开始: {}", response.getName());
            }

            @Override
            public void onSentenceBegin(FlowingSpeechSynthesizerResponse response) {

            }

            // 收到语音合成的语音二进制数据
            @Override
            public void onAudioData(ByteBuffer message) {
                if (isInterrupted.get()) return;

                isPlaying.set(true);
                byte[] audioData = new byte[message.remaining()];
                message.get(audioData);
                logger.info("接收到音频数据，长度: {}", audioData.length); // 记录音频数据长度

                if (audioData.length > 0) {
                    sendAudioData(audioData);
                } else {
                    logger.warn("接收到空音频数据，跳过发送");
                }
            }

            private void sendAudioData(byte[] audioData) {
                // 检查 WebSocket 会话是否打开
                if (!session.isOpen()) {
                    logger.warn("WebSocket 连接已关闭，无法发送音频数据");
                    return;
                }
                synchronized (this) {
                    try {
                        session.sendMessage(new BinaryMessage(audioData));
                        logger.info("已发送音频数据到前端");
                    } catch (IOException e) {
                        logger.error("发送音频数据失败", e);
                    } catch (IllegalStateException e) {
                        logger.warn("WebSocket 连接状态不正确，无法发送数据: {}", e.getMessage());
                        // 可以考虑重试逻辑或其他处理
                    }
                }
            }

            @Override
            public void onSentenceEnd(FlowingSpeechSynthesizerResponse response) {

            }

            // 流式文本语音合成结束
            @Override
            public void onSynthesisComplete(FlowingSpeechSynthesizerResponse response) {
                logger.info("合成完成: {}", response.getName());
            }

            // 处理合成失败
            @Override
            public void onFail(FlowingSpeechSynthesizerResponse response) {
                logger.error("合成失败, 状态: {}, 错误信息: {}", response.getStatus(), response.getStatusText());
            }

            @Override
            public void onSentenceSynthesis(FlowingSpeechSynthesizerResponse response) {

            }
        };
    }

    public void startSynthesis() {
        try {

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void sendSynthesis(String[] textArray) {
        try {
            synthesizer = new FlowingSpeechSynthesizer(client, createSynthesizerListener());
            synthesizer.setAppKey(appKey);
            synthesizer.setFormat(OutputFormatEnum.WAV);
            synthesizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
            synthesizer.setVoice("aiye");
            synthesizer.setVolume(50);
            synthesizer.setPitchRate(0);
            synthesizer.setSpeechRate(0);
            synthesizer.start(); // 确保合成器已启动

            for (String text : textArray) {
                session.sendMessage(new TextMessage(TTS_PREFIX + text));
                synthesizer.send(text); // 发送文本进行合成
            }

            synthesizer.stop(); // 通知合成器停止接收文本
        } catch (Exception e) {
            logger.error("语音合成失败", e);
        } finally {
            if (synthesizer != null) {
                synthesizer.close(); // 关闭合成器
            }
        }
    }

    private boolean containsOnlyChinese(String text) {
        return text != null && text.matches("^[\u4e00-\u9fa5]+$");
    }

    public void stopSynthesis() {
        try {
            //synthesizer.stop();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void shutdown() {
        if (client != null) {
            client.shutdown();
        }
    }
}
